/** 
 * SplitPaneFactory.java
 * @author Lex
 * 2007-9-12 ����03:40:18
 */
package org.lex.swing;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.ref.SoftReference;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.plaf.SplitPaneUI;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;

import org.lex.swing.tab.CloseHeader;


public class ContainerFactory {
	public static final int DEFAULT_DIVIDER_SIZE = 5;

	/**
	 * Borderless SplitPane
	 */
	public static JSplitPane createBorderlessSplitPane(int orientation, int dividerSize) {
		JSplitPane split = ContainerFactory.createBorderlessSplitPane(dividerSize);
		split.setOrientation(orientation);
		return split;
	}

	public static JSplitPane createBorderlessSplitPane(int dividerSize) {
		JSplitPane split = new JSplitPane();
		split.setDividerSize(dividerSize);
		setSplitPaneBorderless(split);
		return split;
	}

	public static JSplitPane createBorderlessSplitPane() {
		return createBorderlessSplitPane(DEFAULT_DIVIDER_SIZE);
	}

	public static boolean setSplitPaneBorderless(final JSplitPane split) {
		JSplitPaneUIListener.getInstance().addSplitPane(split);
		split.setBorder(BorderFactory.createEmptyBorder());
		SplitPaneUI ui = split.getUI();
		boolean borderless = false;
		if (ui instanceof BasicSplitPaneUI) {
			BasicSplitPaneDivider d = ((BasicSplitPaneUI) ui).getDivider();
			d.setBorder(BorderFactory.createEmptyBorder());
			d.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent e) {
					if (2 == e.getClickCount() && MouseEvent.BUTTON1 == e.getButton()) {
						if (JSplitPane.HORIZONTAL_SPLIT == split.getOrientation())
							split.setDividerLocation(split.getWidth() / 2);
						else
							split.setDividerLocation(split.getHeight() / 2);
					}
				}
			});
			borderless = true;
		}
		split.repaint();
		return borderless;
	}

	static class JSplitPaneUIListener implements PropertyChangeListener {
		private static final JSplitPaneUIListener instance;
		static {
			instance = new JSplitPaneUIListener();
			UIManager.addPropertyChangeListener(instance);
		}
		private Vector<SoftReference<JSplitPane>> panes = new Vector<SoftReference<JSplitPane>>();

		public static JSplitPaneUIListener getInstance() {
			return instance;
		}

		public void addSplitPane(JSplitPane split) {
			// this.panes.add( new SoftReference<JSplitPane>( split ) );
		}

		public void propertyChange(PropertyChangeEvent e) {
			if (e.getPropertyName().equals("lookAndFeel")) {
				for (SoftReference<JSplitPane> pane : panes)
					if (null != pane.get())
						setSplitPaneBorderless(pane.get());
			}
		}
	}

	/**
	 * A JTabbedPane, each Tab has a small "Close" buttonon the LINE_END egde
	 */
	public static JTabbedPane createCloseTabPane() {
		return new JTabbedPane() {
			@Override
			public void insertTab(String title, Icon icon, final Component component, String tip, int index) {
				CloseHeader header = new CloseHeader();
				header.setTitle(title);
				header.setIcon(icon);
				header.setToolTip(tip);
				header.getButton().addActionListener(new ActionListener() {
					private Component c = component;

					@Override
					public void actionPerformed(ActionEvent e) {
						removeTabAt(indexOfComponent(c));
					}
				});
				super.insertTab(null, null, component, null, index);
				super.setTabComponentAt(index, header);
			}
		};
	}

	public static JPanel createTitledPane(Component comp, String title) {
		JPanel pane = new JPanel(new BorderLayout());
		pane.add("Center", comp);
		pane.add("North", new JLabel(title, SwingConstants.LEADING));
		return pane;
	}
}
